#ifndef ZUC3_UTIL_MEMPOOL_H
#define ZUC3_UTIL_MEMPOOL_H
#include <cstdint>
#include <cassert>
#include <mutex>
#include <list>
namespace jkutil {
template <typename T> class MemPool
{
public:
    MemPool(size_t cnt)
    {
        cnt_ = cnt;
        buff_ = new T[cnt];
        for (int i = 0; i < cnt; i++) { freeLists_.push_back(buff + i); }
    }
    ~MemPool()
    {
        std::lock_guard<std::mutex> l(m_mutex);
        delete[] buff_;
        buff_ = nullptr;
    }
    T* get(bool clear = true, int* err = nullptr)
    {
        std::lock_guard<std::mutex> l(m_mutex);
        if (size() <= 0)
            return nullptr;
        T* ret = freeLists_.back();
        freeLists_.pop_back();
        memset(ret, 0, sizeof(T));
        return ret;
    }
    int put(const T* val)
    {
        std::lock_guard<std::mutex> l(m_mutex);
        uint64_t off = val - buff_;
        assert((val - buff_) >= 0);                 //大于最低地址
        assert((val - buff_) <= &buff_[cnt_ - 1]);  //小于最高地址
        assert((val - buff_) % sizeof(T) == 0);     //对齐整倍数地址
        freeLists_.push_back(val);
        return -1;
    }
    size_t size() const { return freeLists_.size(); }

private:
    T* buff_;
    size_t cnt_;
    std::list<T*> freeLists_;
    std::mutex mutex_;
};
}  // namespace jkutil

#endif